﻿using System;
using System.Drawing;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32.SafeHandles;

namespace BGShell.Interop
{
    internal static class NativeMethods
    {
        #region kernel32!CreateFileMappingW

        [DllImport("kernel32",
            SetLastError = true,
            ExactSpelling = true,
            CharSet = CharSet.Unicode
        )]
        internal static extern SafeFileHandle CreateFileMappingW(
            [In] IntPtr hFile,
            [In] IntPtr lpAttributes,
            [In] FileMappingFlags dwProtect,
            [In] Int32 dwMaximumSizeHigh,
            [In] Int32 dwMaximumSizeLow,
            [In, MarshalAs(UnmanagedType.LPWStr)]
                 String lpName);

        #endregion

        #region kernel32!MapViewOfFile

        [DllImport("kernel32",
            SetLastError = true,
            ExactSpelling = true,
            CharSet = CharSet.Unicode
        )]
        internal static extern SafeFileViewHandle MapViewOfFile(
            [In] SafeFileHandle hFileMappingObject,
            [In] FileViewFlags dwDesiredAcces,
            [In] Int32 dwFileOffsetHigh,
            [In] Int32 dwFileOffsetLow,
            [In] IntPtr dwNumberOfBytesToMap);

        #endregion

        #region kernel32!UnmapViewOfFile

        [DllImport("kernel32",
            SetLastError = true,
            ExactSpelling = true,
            CharSet = CharSet.Unicode
        )]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern bool UnmapViewOfFile(
            [In] IntPtr lpBaseAddress);

        #endregion

        #region kernel32!SetLastError

        [DllImport("kernel32",
            SetLastError = true,
            ExactSpelling = true,
            CharSet = CharSet.Unicode
        )]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        internal static extern void SetLastError([In] Int32 dwError);

        #endregion

        #region user32!GetAncestor

        [SuppressUnmanagedCodeSecurity]
        [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern IntPtr GetAncestor(HandleRef hWnd, AncestorType gaFlags);

        #endregion

        #region user32!MapWindowPoints

        [DllImport(
            "user32",
            SetLastError = true,
            ExactSpelling = true,
            CallingConvention = CallingConvention.Winapi
        )]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern int MapWindowPoints(
          [In] HandleRef hWndFrom,
          [In] HandleRef hWndTo,
          [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
               Point[] lpPoints,
          [In] Int32 cPoints
        );

        #endregion

        #region user32!RedrawWindow

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32", CharSet = CharSet.Unicode, ExactSpelling = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern bool RedrawWindow(HandleRef hwnd, IntPtr rcUpdate, IntPtr hrgnUpdate, int flags);
 
        #endregion

        #region user32!RegisterWindowMessageW

        [DllImport("user32", CharSet = CharSet.Unicode, ExactSpelling = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern int RegisterWindowMessageW(
            [In, MarshalAs(UnmanagedType.LPWStr)] String lpString);

        #endregion

        #region user32!SendMessage(IntPtr, UInt32, IntPtr, IntPtr)

        [DllImport(
            "user32",
            SetLastError = true,
            CallingConvention = CallingConvention.Winapi
        )]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        internal static extern IntPtr SendMessage(
            [In] HandleRef hWnd,
            [In] UInt32 Msg,
            [In] IntPtr wParam,
            [In] IntPtr lParam);

        #endregion
    }
}
